package com.freecloud.framework.service;

import com.freecloud.framework.repository.BaseDao;
import com.freecloud.framework.request.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Transient;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @Author: maomao
 * @Date: 2019-06-17 10:37
 */
public abstract class AbstractBaseService<T,ID,R extends BaseDao<T,ID>> extends AbstractService implements InterfaceBaseService<T,ID> {

    @Autowired
    protected R baseDao;

    @Override
    public List<T> findAll(){
        return baseDao.findAll();
    }

    @Override
    public List<T> findAll(Sort sort){
        return baseDao.findAll(sort);
    }

    @Override
    public List<T> findAllById(Iterable<ID> ids){
        return baseDao.findAllById(ids);
    }

    @Override
    @Transactional
    public <S extends T> List<S> saveAll(Iterable<S> entities){
        return baseDao.saveAll(entities);
    }

    @Override
    public void flush(){
        baseDao.flush();
    }

    @Override
    @Transactional
    public <S extends T> S saveAndFlush(S entity){
        return baseDao.saveAndFlush(entity);
    }

    @Override
    @Transactional
    public void deleteInBatch(Iterable<T> entities){
        baseDao.deleteInBatch(entities);
    }

    @Override
    @Transactional
    public int deleteBatch(ID[] ids){
        return baseDao.deleteBatch(ids);
    }

    @Override
    @Transactional
    public void deleteAllInBatch(){
        baseDao.deleteAllInBatch();
    }

    @Override
    public T getOne(ID id){
        return baseDao.getOne(id);
    }

    @Override
    public <S extends T> List<S> findAll(Example<S> example){
        return baseDao.findAll(example);
    }

    @Override
    public <S extends T> List<S> findAll(Example<S> example, Sort sort){
        return baseDao.findAll(example,sort);
    }

    @Override
    public Page<T> findAll(Pageable pageable){
        return baseDao.findAll(pageable);
    }

    @Override
    public <S extends T> Optional<S> findOne(Example<S> example){
        return baseDao.findOne(example);
    }

    @Override
    public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable){
        return baseDao.findAll(example,pageable);
    }

    @Override
    public <S extends T> long count(Example<S> example){
        return baseDao.count(example);
    }

    @Override
    public <S extends T> boolean exists(Example<S> example){ return baseDao.exists(example); }

    @Override
    @Transactional
    public <S extends T> S save(S entity){return baseDao.save(entity);}

    @Override
    public Optional<T> findById(ID id) {
        return baseDao.findById(id);
    }

    @Override
    public boolean existsById(ID id) {
        return baseDao.existsById(id);
    }

    @Override
    public long count() {
        return baseDao.count();
    }

    @Override
    @Transactional
    public void deleteById(ID id) {
        baseDao.deleteById(id);
    }

    @Override
    @Transactional
    public void delete(T entity) {
        baseDao.delete(entity);
    }

    @Override
    @Transactional
    public void deleteAll(Iterable<? extends T> entities) {
        baseDao.deleteAll(entities);
    }


    @Override
    @Transactional
    public void deleteAll() {
        baseDao.deleteAll();
    }


    @Override
    @Transactional
    public T update(T entity){
        return baseDao.save(entity);
    }

    @Override
    public T queryObject(ID id){
        Optional<T> optional = baseDao.findById(id);
        if(!optional.isPresent())
        {
            return null;
        }

        return optional.get();
    }


    @Override
    public List<T> queryList(Map<String,Object> parameter){

        Class<T> TClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

        return baseDao.findAll(Query.getExample(parameter,TClass));
    }
}
